package chatserver.gui;

import chatserver.objects.Server;
import chatserver.objects.ServerConfig;
import chatserver.roles.ChannelRole;
import chatserver.roles.GlobalRole;
import chatserver.roles.Rights;
import chatserver.roles.Role;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;

public class EditRoleWindow extends JDialog {

    private JLabel jLabel1 = new JLabel();
    private JLabel jLabel2 = new JLabel();
    private JTextField jTextFieldRoleName = new JTextField();
    private JTextField jTextFieldRoleProfile = new JTextField();
    private JButton jButtonSave = new JButton();
    private JButton jButtonCancel = new JButton();
    private JTable jTable1 = new JTable();
    private JScrollPane jTable1ScrollPane = new JScrollPane(jTable1);
    private JLabel jLabel3 = new JLabel();
    private boolean isGlobalRole;
    private MainWindow parent;
    private Role role;

    public EditRoleWindow(MainWindow owner, String title, boolean modal, boolean globalRole, Role role) {

        super(owner, title, modal);

        this.isGlobalRole = globalRole;
        this.parent = owner;
        this.role = role;

        setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
        int frameWidth = 700;
        int frameHeight = 303;
        setSize(frameWidth, frameHeight);
        Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
        int x = (d.width - getSize().width) / 2;
        int y = (d.height - getSize().height) / 2;
        setLocation(x, y);
        Container cp = getContentPane();
        cp.setLayout(null);


        jLabel1.setBounds(16, 24, 75, 25);
        jLabel1.setText("Role name:");
        cp.add(jLabel1);
        jLabel2.setBounds(16, 112, 106, 25);
        jLabel2.setText("Role profile name:");
        cp.add(jLabel2);
        jTextFieldRoleName.setBounds(48, 64, 193, 25);
        cp.add(jTextFieldRoleName);
        jTextFieldRoleProfile.setBounds(48, 152, 193, 25);
        cp.add(jTextFieldRoleProfile);
        jButtonSave.setBounds(32, 216, 97, 33);
        jButtonSave.setText("Save");
        jButtonSave.setMargin(new Insets(2, 2, 2, 2));
        jButtonSave.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent evt) {
                jButtonAdd_ActionPerformed(evt);
            }
        });
        cp.add(jButtonSave);
        jButtonCancel.setBounds(168, 216, 105, 33);
        jButtonCancel.setText("Cancel");
        jButtonCancel.setMargin(new Insets(2, 2, 2, 2));
        jButtonCancel.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent evt) {
                jButtonCancel_ActionPerformed(evt);
            }
        });
        cp.add(jButtonCancel);


        DefaultTableModel model = (DefaultTableModel) jTable1.getModel();

        ServerConfig config = Server.getInstance().getConfig();


        jTextFieldRoleName.setEditable(false);
        jTextFieldRoleName.setText(role.getName());
        jTextFieldRoleProfile.setText(role.getProfile());

        if (globalRole) {
            GlobalRole grole = (GlobalRole) role;
            List<GlobalRole> groles = config.getGlobalRoles();

            model.setColumnCount(1);
            int i = 0;
            for (Rights.Global right : Rights.Global.values()) {

                boolean hasRight = false;
                List<GlobalRole> selectedRoles = null;
                if (grole.getRights().containsKey(right)) {
                    hasRight = true;
                    List<Integer> iList = grole.getRights().get(right);
                    selectedRoles = new ArrayList<GlobalRole>();
                    for (GlobalRole curRole : groles) {
                        if (iList.contains(curRole.getSqlId())) {
                            selectedRoles.add(curRole);
                        }
                    }
                }
                model.insertRow(i, new Object[]{new RightListItem<GlobalRole>(right.toString(), hasRight, right.hasModifier(), groles, selectedRoles)});
                i++;
            }
        } else {
            ChannelRole crole = (ChannelRole) role;
            List<ChannelRole> croles = config.getChannelRoles();

            model.setColumnCount(1);
            int i = 0;
            for (Rights.Channel right : Rights.Channel.values()) {

                boolean hasRight = false;
                List<ChannelRole> selectedRoles = null;
                if (crole.getRights().containsKey(right)) {
                    hasRight = true;
                    List<Integer> iList = crole.getRights().get(right);
                    selectedRoles = new ArrayList<ChannelRole>();
                    for (ChannelRole curRole : croles) {
                        if (iList.contains(curRole.getSqlId())) {
                            selectedRoles.add(curRole);
                        }
                    }
                }
                model.insertRow(i, new Object[]{new RightListItem<ChannelRole>(right.toString(), hasRight, right.hasModifier(), croles, selectedRoles)});
                i++;
            }
        }


        jTable1.setTableHeader(null);
        jTable1.setRowHeight(35);

        jTable1ScrollPane.setBounds(310, 48, 360, 177);
        cp.add(jTable1ScrollPane);

        int vColIndex = 0;
        TableColumn col = jTable1.getColumnModel().getColumn(vColIndex);
        col.setCellEditor(new RightListEditor());

        col.setCellRenderer(new RightListRenderer());


        jTable1.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

        jLabel3.setBounds(305, 24, 51, 19);
        jLabel3.setText("Rights:");
        cp.add(jLabel3);

        setResizable(false);
        setVisible(true);
    }

    public void jButtonAdd_ActionPerformed(ActionEvent evt) {

        ServerConfig config = Server.getInstance().getConfig();

        String profile = jTextFieldRoleProfile.getText().toLowerCase();
        if (isGlobalRole) {
            if (!profile.equals(role.getProfile())
                    && config.isGlobalProfileTaken(profile)) {
                JOptionPane.showMessageDialog(this, "Profile name is already in use!", "error", JOptionPane.ERROR_MESSAGE);
                return;
            }
        } else {
            if (!profile.equals(role.getProfile())
                    && config.isChannelProfileTaken(profile)) {
                JOptionPane.showMessageDialog(this, "Profile name is already in use!", "error", JOptionPane.ERROR_MESSAGE);
                return;
            }
        }


        DefaultTableModel model = (DefaultTableModel) jTable1.getModel();

        Map<String, List<Integer>> rights = new HashMap<String, List<Integer>>();

        for (int i = 0; i < model.getRowCount(); i++) {
            RightListItem item = (RightListItem) model.getValueAt(i, 0);

            if (!item.isSelected()) {
                continue;
            }

            List<Integer> modifiers;

            if (!item.hasModifier()) {
                modifiers = new ArrayList<Integer>();
                modifiers.add(Role.NO_RIGHT_MODIFIER);
            } else {
                modifiers = item.getSelectedRoleIds();
            }

            rights.put(item.getName(), modifiers);
        }


        if (isGlobalRole) {
            Map<Rights.Global, List<Integer>> eRights = new EnumMap<Rights.Global, List<Integer>>(Rights.Global.class);
            for (Entry<String, List<Integer>> entry : rights.entrySet()) {
                try {
                    Rights.Global right = Rights.Global.valueOf(entry.getKey());
                    eRights.put(right, entry.getValue());
                } catch (Exception e) {
                }
            }     
            
            GlobalRole globalRole = (GlobalRole) role;
            globalRole.setProfile(profile);
            globalRole.setRights(eRights);
            globalRole.save(false);
            dispose();
        } else {
            Map<Rights.Channel, List<Integer>> eRights = new EnumMap<Rights.Channel, List<Integer>>(Rights.Channel.class);
            for (Entry<String, List<Integer>> entry : rights.entrySet()) {
                try {
                    Rights.Channel right = Rights.Channel.valueOf(entry.getKey());
                    eRights.put(right, entry.getValue());
                } catch (Exception e) {
                }
            }   
            
            ChannelRole channelRole = (ChannelRole) role;
            channelRole.setProfile(profile);
            channelRole.setRights(eRights);
            channelRole.save(false);
            dispose();
        }

    }

    public void jButtonCancel_ActionPerformed(ActionEvent evt) {
        dispose();
    }
}
